package com.sansan.qiangji.realize.base;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sansan.qiangji.VO.base.product.ProductListResultVO;
import com.sansan.qiangji.VO.base.product.ProductVO;
import com.sansan.qiangji.dto.ProductExcelDto;
import com.sansan.qiangji.entity.base.Product;
import com.sansan.qiangji.entity.base.example.ProductExample;
import com.sansan.qiangji.enums.ResultEnum;
import com.sansan.qiangji.exception.ServiceException;
import com.sansan.qiangji.form.base.ProductAddForm;
import com.sansan.qiangji.form.base.ProductEditForm;
import com.sansan.qiangji.form.base.ProductListForm;
import com.sansan.qiangji.service.inter.base.ProductService;
import com.sansan.qiangji.service.inter.base.ProductTypeService;
import com.sansan.qiangji.utils.CopyUtil;
import com.sansan.qiangji.utils.pageUtils.PageResult;
import com.sansan.qiangji.utils.pageUtils.PageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ProductReal {

    @Autowired
    private ProductService productService;
    @Autowired
    private ProductTypeService productTypeService;

    @Transactional
    public void deleteProduct(Integer productId) {
        Product product = productService.selectByPrimaryKey(productId);
        if (product == null) {
            log.error("【物品删除】物品不存在，productId={}", productId);
            throw new ServiceException(ResultEnum.PRODUCT_IS_NOT_EXIST);
        }
        int row = productService.deleteByPrimaryKey(productId);
        if (row == 0) {
            log.error("【物品删除】物品删除失败，productId={}", productId);
            throw new ServiceException(ResultEnum.PRODUCT_DELETE_ERROR);
        }
    }

    @Transactional
    public void addProduct(ProductAddForm productAddForm) {
        List<Product> productList = productService.findByProductCodeOrProductName(productAddForm.getProductCode(), productAddForm.getProductName());
        if (productList.size() > 0) {
            log.error("【物品新增】该物品名称或编号已存在，productAddForm={}", productAddForm.toString());
            throw new ServiceException(ResultEnum.PRODUCT_IS_EXIST);
        }
        Product product = new Product();
        BeanUtils.copyProperties(productAddForm, product);
        product.setPicture("无");
        int row = productService.insert(product);
        if (row == 0) {
            log.error("【物品新增】物品新增失败");
            throw new ServiceException(ResultEnum.PRODUCT_INSERT_ERROR);
        }
    }

    @Transactional
    public void insertProducts(List<Product> products) {
        productService.insertProducts(products);
    }

    @Transactional
    public void editProduct(ProductEditForm productEditForm) {
        Product product = productService.selectByPrimaryKey(productEditForm.getProductId());
        if (product == null) {
            log.error("【编辑物品】物品不存在，productEditForm={}", productEditForm.toString());
            throw new ServiceException(ResultEnum.PRODUCT_IS_NOT_EXIST);
        }
        CopyUtil.copyPropertiesNotNull(productEditForm, product);
        int row = productService.updateByPrimaryKey(product);
        if (row == 0) {
            log.error("【物品新增】物品新增失败");
            throw new ServiceException(ResultEnum.PRODUCT_INSERT_ERROR);
        }
    }

    @Transactional
    public void editProductCondition(ProductEditForm productEditForm) {
        Product product = new Product();
        BeanUtils.copyProperties(productEditForm, product);
        int row = productService.updateByPrimaryKeySelective(product);
        if (row == 0) {
            log.error("【物品新增】物品新增失败");
            throw new ServiceException(ResultEnum.PRODUCT_INSERT_ERROR);
        }
    }

    public ProductListResultVO productList(ProductListForm productListForm) {
        ProductExample example = new ProductExample();
        List<Map<String, Object>> productTypeList = productTypeService.getProductTypeList();
        int pageNum = productListForm.getPageNum();
        int pageSize = productListForm.getPageSize();
        PageHelper.startPage(pageNum, pageSize);
        ProductExample.Criteria criteria = example.createCriteria();
        if (productListForm.getProductCode() != null && !"".equals(productListForm.getProductCode())) {
            criteria.andProductCodeLike("%" + productListForm.getProductCode() + "%");
        }
        if (productListForm.getProductName() != null && !"".equals(productListForm.getProductName())) {
            criteria.andProductNameLike("%" + productListForm.getProductName() + "%");
        }
        if (productListForm.getProductName() != null && productListForm.getIsHavePicture().equals("false")){
            criteria.andPictureEqualTo("无");
        }
        List<Product> productList = productService.selectByExample(example);
        PageResult<Product> productPageResult = PageUtil.getPageResult(new PageInfo<>(productList));
        ProductListResultVO productListResultVO = new ProductListResultVO();
        BeanUtils.copyProperties(productPageResult, productListResultVO);
        List<ProductVO> productVOS = new ArrayList<>();
        for (Product product : productPageResult.getContent()) {
            ProductVO productVO = new ProductVO();
            BeanUtils.copyProperties(product, productVO);
            productVOS.add(productVO);
        }
        productListResultVO.setProductVOS(productVOS);
        productListResultVO.setProductTypeVOS(productTypeList);
        return productListResultVO;
    }

    public ProductListResultVO productListCondition(ProductListForm productListForm) {
        int pageNum = productListForm.getPageNum();
        int pageSize = productListForm.getPageSize();
        PageHelper.startPage(pageNum, pageSize);

        List<Product> productList = productService.selectListCondition(productListForm);
        PageResult<Product> productPageResult = PageUtil.getPageResult(new PageInfo<>(productList));
        ProductListResultVO productListResultVO = new ProductListResultVO();
        BeanUtils.copyProperties(productPageResult, productListResultVO);
        List<ProductVO> productVOS = new ArrayList<>();
        for (Product product : productPageResult.getContent()) {
            ProductVO productVO = new ProductVO();
            BeanUtils.copyProperties(product, productVO);
            productVOS.add(productVO);
        }
        productListResultVO.setProductVOS(productVOS);
        return productListResultVO;
    }

    @Transactional
    public ProductVO upLoadProductPic(String productCode, MultipartFile file) {
        ProductExample example = new ProductExample();
        example.or().andProductCodeEqualTo(productCode);
        List<Product> productList = productService.selectByExample(example);
        if (productList.size() == 0) {
            log.error("【物料图片上传】物品不存在，productCode={}", productCode);
            throw new ServiceException(ResultEnum.PRODUCT_IS_NOT_EXIST);
        }
        String contentType = file.getContentType();
        if (contentType == null || (!contentType.equals("image/jpeg") && !contentType.equals("image/png") && !contentType.equals("image/jpg"))) {
            log.error("【物料图片上传】只能上传JPG/PNG类型的图片，productCode={}", productCode);
            throw new ServiceException(ResultEnum.PRODUCT_ONLY_CAN_BE_JPG_PNG);
        }
        byte[] imageBytes;
        try {
            imageBytes = file.getBytes();
        } catch (Exception e) {
            log.error("【物料图片上传】获取图片数据流失败");
            throw new ServiceException(ResultEnum.GET_PRODUCT_BYTE_ERROR);
        }
        if (imageBytes.length / 1024 / 1024 > 1) {
            log.error("【物料图片上传】图片大小不能超过1MB !");
            throw new ServiceException(ResultEnum.PRODUCT_SIZE_CAN_TOO_LAGER);
        }
        BASE64Encoder base64Encoder = new BASE64Encoder();
        String baseEncoderImg = "data:" + contentType + ";base64," + base64Encoder.encode(imageBytes);
        baseEncoderImg = baseEncoderImg.replaceAll("[\\s*\t\n\r]", "");
        productList.get(0).setPicture(baseEncoderImg);
        productService.updateByPrimaryKey(productList.get(0));
        ProductVO productVO = new ProductVO();
        BeanUtils.copyProperties(productList.get(0), productVO);
        return productVO;
    }

    public ProductVO findByProductCode(String productCode) {
        ProductVO productVO = new ProductVO();
        ProductExample productExample = new ProductExample();
        productExample.or().andProductCodeEqualTo(productCode);
        List<Product> products = productService.selectByExample(productExample);
        if (products.size() == 0) {
            log.error("【查找物料】物料不存在");
            throw new ServiceException(ResultEnum.PRODUCT_IS_NOT_EXIST);
        }
        BeanUtils.copyProperties(products.get(0), productVO);
        return productVO;
    }

    public void upLoadProductExcel(List<ProductExcelDto> productExcelDtos) {
        List<Product> products = new ArrayList<>();
        for (ProductExcelDto productExcelDto : productExcelDtos) {
            Product product = new Product();
            BeanUtils.copyProperties(productExcelDto, product);
            product.setPicture("无");
            products.add(product);
        }
        List<Product> productList = productService.selectProducts(products);
        int index = 0;
        for (Product product : productList) {
            List<Product> products1 = products.stream().filter(e -> e.getProductName().equals(product.getProductName()) || e.getProductCode().equals(product.getProductCode())).collect(Collectors.toList());
            for (Product product1 : products1) {
                products.remove(product1);
            }
            products1.get(0).setProductId(productList.get(index).getProductId());
            if (products1.size() > 0) {
                BeanUtils.copyProperties(products1.get(0), productList.get(index));
            }
            index++;
        }
        if (productList.size() != 0) {
            productService.updateProducts(productList);
        }
        if (products.size() != 0) {
            insertProducts(products);
        }
    }

    public List<ProductExcelDto> getAllProductDto() {
        ProductExample example = new ProductExample();
        List<Product> products = productService.selectByExample(example);
        List<ProductExcelDto> productExcelDtos = new ArrayList<>();
        for (Product product : products) {
            ProductExcelDto productExcelDto = new ProductExcelDto();
            BeanUtils.copyProperties(product, productExcelDto);
            productExcelDtos.add(productExcelDto);
        }
        return productExcelDtos;
    }
}
